﻿using KinonekoSoftware.Foundation;
using System.Reactive.Concurrency;
using KinonekoSoftware.Extensions.Ioc;
using KinonekoSoftware.Foundation.Patterns;
using KinonekoSoftware.Foundation.UI;
using KinonekoSoftware.Foundation.UI.Core;
using KinonekoSoftware.Foundation.UI.ViewModels;
using NLog;

namespace KinonekoSoftware.Foundation
{
    public abstract partial class ManagedLifetimeObject : IManagedLifetimeObject
    {


        //
        //
        private static readonly Lazy<IScheduler> SchedulerLazy = new Lazy<IScheduler>(Ioc.Get<IScheduler>);

        //
        //
        private readonly DisposableCollection _collector = new DisposableCollection();



        //-------------------------------------------------------------
        //
        //          IDisposableCollector
        //
        //-------------------------------------------------------------



        #region IDisposableCollector

        public void Collect(IDisposable disposable)
        {
            if (disposable is null) return;
            _collector.Collect(disposable);
        }

        #endregion





        //-------------------------------------------------------------
        //
        //          Receive
        //
        //-------------------------------------------------------------


        #region Receive

        /// <summary>
        /// 接受参数
        /// </summary>
        /// <param name="parameter">指定要接收的参数。</param>
        public void Receive(object parameter)
        {
            if (parameter is null)
            {
                State = State | ViewModelState.ParameterReceivedButNoParameter;
            }
            else
            {
                State = State | ViewModelState.ParameterReceived;
                OnReceive(parameter);
            }
        }

        /// <summary>
        /// 接受参数
        /// </summary>
        /// <param name="parameter">指定要接收的参数。</param>
        protected virtual void OnReceive(object parameter)
        {
        }

        #endregion


        //-------------------------------------------------------------
        //
        //          Start
        //
        //-------------------------------------------------------------


        #region Start

        /// <summary>
        /// 启动一个视图模型，注意：视图模型只能启动一次。
        /// </summary>
        public void Start()
        {
            if (IsInitialized)
            {
                return;
            }

            try
            {
                StartBefore();
                OnStart();
                StartAfter();
                State = ViewModelState.Initialized | ViewModelState.Start;
            }
            catch(Exception ex)
            {
                Ioc.Get<ILogger>().Error(ex);
                State = ViewModelState.Exception | ViewModelState.NotInitialized | ViewModelState.Start;
            }
        }

        /// <summary>
        /// 启动一个视图模型
        /// </summary>
        protected virtual void StartBefore()
        {
        }

        /// <summary>
        /// 启动一个视图模型
        /// </summary>
        protected virtual void OnStart()
        {
        }

        /// <summary>
        /// 启动一个视图模型
        /// </summary>
        protected virtual void StartAfter()
        {
        }

        #endregion


        //-------------------------------------------------------------
        //
        //          Suspend
        //
        //-------------------------------------------------------------


        #region Suspend

        public void Suspend()
        {
            if (!IsInitialized)
            {
                return;
            }

            try
            {
                SuspendBefore();
                OnSuspend();
                SuspendAfter();

                State = ViewModelState.Initialized | ViewModelState.Suspend;
            }
            catch(Exception ex)
            {
                Ioc.Get<ILogger>().Error(ex);
                State = ViewModelState.Exception | ViewModelState.NotInitialized | ViewModelState.Suspend;
            }
        }

        protected virtual void SuspendBefore()
        {
        }

        protected virtual void OnSuspend()
        {
        }

        protected virtual void SuspendAfter()
        {
        }

        #endregion


        //-------------------------------------------------------------
        //
        //          Resume
        //
        //-------------------------------------------------------------


        #region Resume

        public void Resume()
        {
            if (!IsInitialized)
            {
                return;
            }

            try
            {
                ResumeBefore();
                OnResume();
                ResumeAfter();

                State = ViewModelState.Initialized | ViewModelState.Resume;
            }
            catch(Exception ex)
            {
                Ioc.Get<ILogger>().Error(ex);
                State = ViewModelState.Exception | ViewModelState.NotInitialized | ViewModelState.Resume;
            }
        }

        protected virtual void ResumeBefore()
        {
        }

        protected virtual void OnResume()
        {
        }

        protected virtual void ResumeAfter()
        {
        }

        #endregion


        //-------------------------------------------------------------
        //
        //          Stop
        //
        //-------------------------------------------------------------


        #region Stop

        /// <summary>
        /// 
        /// </summary>
        public void Stop()
        {
            // TODO: 后期检查是否需要移除exit标志
            if (!IsInitialized)
            {
                return;
            }

            try
            {
                StopBefore();
                OnStop();
                StopAfter();
                Dispose();
                Disposable.Dispose();
                State = ViewModelState.Initialized | ViewModelState.Stop;
            }
            catch(Exception ex)
            {
                Ioc.Get<ILogger>().Error(ex);
                State = ViewModelState.Exception | ViewModelState.NotInitialized | ViewModelState.Stop;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        protected virtual void StopBefore()
        {
        }

        /// <summary>
        /// 
        /// </summary>
        protected virtual void OnStop()
        {
        }

        /// <summary>
        /// 
        /// </summary>
        protected virtual void StopAfter()
        {
        }

        #endregion



        //-------------------------------------------------------------
        //
        //          Properties
        //
        //-------------------------------------------------------------

        /// <summary>
        /// 垃圾回收器
        /// </summary>
        protected DisposableCollection Disposable => _collector;


        /// <summary>
        /// 获得当前的调度器
        /// </summary>
        public IScheduler Scheduler => SchedulerLazy.Value;

        /// <summary>
        /// 当前视图模型的状态
        /// </summary>
        public ViewModelState State { get; private set; }

        /// <summary>
        /// 是否已经初始化了
        /// </summary>
        public bool IsInitialized => State.HasFlag(ViewModelState.Initialized);


        ~ManagedLifetimeObject()
        {
            Dispose(false);
        }
    }

}